package com.zl.service.impl;

import cn.hutool.core.util.StrUtil;
import com.zl.common.Result;
import com.zl.dto.MenuDto;
import com.zl.dto.MenuMetaDto;
import com.zl.dto.TsMenuDto;
import com.zl.dto.TsRoleSmallDto;
import com.zl.entity.TsMenu;
import com.zl.mapper.MenuMapper;
import com.zl.mapper.RolesMenusMapper;
import com.zl.service.MenuService;
import com.zl.util.Exceptions;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections4.CollectionUtils;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.*;
import java.util.stream.Collectors;

@Slf4j
@Service("menuService")
public class MenuServiceImpl implements MenuService {

    @Resource
    private MenuMapper menuMapper;

    @Resource
    private RolesMenusMapper rolesMenusMapper;

    @Override
    public List<TsMenu> all(TsMenuDto menuDto) {
        return menuMapper.all(menuDto);
    }

    @Override
    public Map buildTree(List<TsMenu> menus) {
        List<TsMenu> trees = new ArrayList<>();
        menus.forEach(menu -> {
            //是否存下级菜单
            if (menu.getPid().equals("0")) {
                trees.add(menu);
            }
            menus.forEach(it -> {
                if (it.getPid().equals(menu.getId())) {
                    if (CollectionUtils.isEmpty(menu.getChildren())) {
                        menu.setChildren(new ArrayList<>());
                    }
                    menu.getChildren().add(it);
                }
            });
        });
        Map map = new HashMap();
        map.put("content", trees.size() == 0 ? menus : trees);
        map.put("totalElements", menus.size());
        return map;
    }

    @Override
    public Result create(TsMenuDto resources) {
        try {
            if (menuMapper.findByName(resources.getName()) != null) {
                return Result.error(resources.getName() + "菜单名存在");
            }
        /*if(resources.getIFrame()){
            if (!(resources.getPath().toLowerCase().startsWith("http://")||resources.getPath().toLowerCase().startsWith("https://"))) {
                throw new BadRequestException("外链必须以http://或者https://开头");
            }
        }*/
            menuMapper.save(resources);
            return Result.success();
        } catch (Exception e) {
            log.error("创建菜单异常：{}", Exceptions.getStackTraceAsString(e));
            return Result.error();
        }
    }

    @Override
    public Result update(TsMenuDto resources) {
        try {
            if (resources.getId().equals(resources.getPid())) {
                return Result.error("上级不能为自己");
            }

        /*if(resources.getIFrame()){
            if (!(resources.getPath().toLowerCase().startsWith("http://")||resources.getPath().toLowerCase().startsWith("https://"))) {
                throw new BadRequestException("外链必须以http://或者https://开头");
            }
        }*/
            menuMapper.update(resources);
            return Result.success();
        } catch (Exception e) {
            log.error("修改菜单异常：{}", Exceptions.getStackTraceAsString(e));
            return Result.error();
        }
    }

    @Override
    public Result delete(Long id) {

        //查询下级菜单
        try {
            List<TsMenu> menus = menuMapper.findByPid(id);
            List<Long> menusIds = menus.stream().map(TsMenu::getId).collect(Collectors.toList());
            menusIds.add(id);
            rolesMenusMapper.del(menusIds);
            menuMapper.del(menusIds);
            return Result.success();
        } catch (Exception e) {
            log.error("删除菜单异常：{}", Exceptions.getStackTraceAsString(e));
            return Result.error();
        }

    }

    @Override
    public Result getMenuTree() {
        try {
            List<TsMenu> menus = menuMapper.findByPid(0L);
            return Result.success(menuTree(menus));
        } catch (Exception e) {
            log.error("获取菜单异常：{}", Exceptions.getStackTraceAsString(e));
            return Result.error();
        }
    }

    @Override
    public List<TsMenu> findByRoles(List<TsRoleSmallDto> roles) {
        List<TsMenu> menus = new ArrayList<>();
        for (TsRoleSmallDto role : roles) {
            List<TsMenu> menus1 = menuMapper.findByRolesId(role.getId()).stream().collect(Collectors.toList());
            menus.addAll(menus1);
        }
        return menus;
    }

    @Override
    public List<MenuDto> buildMenus(List<TsMenu> menusTree) {
        List<MenuDto> list = new LinkedList<>();
        menusTree.forEach(menu -> {
                    if (menu != null) {
                        List<TsMenu> menuDTOList = menu.getChildren();
                        MenuDto menuVo = new MenuDto();
                        menuVo.setName(menu.getName());
                        menuVo.setPath(menu.getPath());

                        // 如果不是外链
                        if (!menu.getIFrame()) {
                            if (menu.getPid().equals(0L)) {
                                //一级目录需要加斜杠，不然访问 会跳转404页面
                                menuVo.setPath("/" + menu.getPath());
                                menuVo.setComponent(StrUtil.isEmpty(menu.getComponent()) ? "Layout" : menu.getComponent());
                            } else if (!StrUtil.isEmpty(menu.getComponent())) {
                                menuVo.setComponent(menu.getComponent());
                            }
                        }
                        menuVo.setMeta(new MenuMetaDto(menu.getName(), menu.getIcon()));
                        if (menuDTOList != null && menuDTOList.size() != 0) {
                            menuVo.setAlwaysShow(true);
                            menuVo.setRedirect("noredirect");
                            menuVo.setChildren(buildMenus(menuDTOList));
                            // 处理是一级菜单并且没有子菜单的情况
                        } else if (menu.getPid().equals(0L)) {
                            MenuDto menuVo1 = new MenuDto();
                            menuVo1.setMeta(menuVo.getMeta());
                            // 非外链
                            if (!menu.getIFrame()) {
                                menuVo1.setPath("index");
                                menuVo1.setName(menuVo.getName());
                                menuVo1.setComponent(menuVo.getComponent());
                            } else {
                                menuVo1.setPath(menu.getPath());
                            }
                            menuVo.setName(null);
                            menuVo.setMeta(null);
                            menuVo.setComponent("Layout");
                            List<MenuDto> list1 = new ArrayList<>();
                            list1.add(menuVo1);
                            menuVo.setChildren(list1);
                        }
                        list.add(menuVo);
                    }
                }
        );
        return list;
    }



    private List<Map<String, Object>> menuTree(List<TsMenu> menus) {
        List<Map<String, Object>> list = new LinkedList<>();
        menus.forEach(menu -> {
                    if (menu != null) {
                        List<TsMenu> menuList = menuMapper.findByPid(menu.getId());
                        Map<String, Object> map = new HashMap<>();
                        map.put("id", menu.getId());
                        map.put("label", menu.getName());
                        if (menuList != null && menuList.size() != 0) {
                            map.put("children", menuTree(menuList));
                        }
                        list.add(map);
                    }
                }
        );
        return list;
    }
}
